package chess;

import gnu.io.*;
import java.io.*;
import java.util.TooManyListenersException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Class declaration
 *
 *
 * @author
 * @version 1.8, 08/03/00
 */
public class Chess implements SerialPortEventListener {
    static CommPortIdentifier portId;
    static Enumeration	      portList;
    InputStream		      inputStream;
    OutputStream              _out;
    SerialPort		      serialPort;
    Thread		      readThread;
    char _chessBoard [][];
    int _xInicial, _xFinal, _yInicial, _yFinal;
    boolean _pendiente;
    boolean _guardar;
    int _contador;
    Board _tablero;

    /**
     * Method declaration
     *
     *
     * @param args
     *
     * @see
     */

    /**
     * Constructor declaration
     *
     *
     * @see
     */
    public Chess(Thread thread, Board tablero) {
        this._tablero = tablero;
                        
	try {
	    serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
	} catch (PortInUseException e) {}

	try {
	    inputStream = serialPort.getInputStream();
            _out = serialPort.getOutputStream();
	} catch (IOException e) {}

	try {
	    serialPort.addEventListener(this);
	} catch (TooManyListenersException e) {}

	serialPort.notifyOnDataAvailable(true);

	try {
	    serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, 
					   SerialPort.STOPBITS_1, 
					   SerialPort.PARITY_NONE);
	} catch (UnsupportedCommOperationException e) {}

        _chessBoard = new char[][]{
        {'1', '1', '1', '1', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0', '0', '0'},
        {'1', '1', '1', '1', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0', '0', '0'},
        {'0', '0', '0', '0', '0', '0', '0', '0'}
    };
        _pendiente = false;
        _guardar = false;
        _contador = 0;
                        
	readThread = new Thread(thread);

	readThread.start();
    }

    /**
     * Method declaration
     *
     *
     * @see
     */

    
    public String concatZero(String s){
         for (int i = s.length();i < 8; i++){
             s = "0".concat(s);
         }
         return s;
    }
    
    public boolean charToBool(char c){
        boolean b;
        b = (c ==  '0') ? false : true;
        return  b;     
    }                
    
   public void compare(char[][] chessBoard){
        boolean equal = true;
        int changes = 0;
        for(int r = 0; r < 8; r ++){
            for(int c=0; c < 8; c++){
                if(changes > 2)
                    break;
                else if(_chessBoard[r][c] != chessBoard[r][c]){
                   changes ++;
                   equal = false;
                   if(chessBoard[r][c] == '0'){ //detecta la posicion inicial
                       _xInicial = r;
                       _yInicial = c;
                       System.out.println(r + ", " + c);
                   }
                   else if(chessBoard[r][c] == '1'){ //detecta la posicion final
                       _xFinal = r;
                       _yFinal = c;
                       System.out.println(r + ", " + c);
                   }                   
              }
            }
        }
        if(!equal){
            System.out.println(changes);
            if(changes == 1){
                System.out.println("esperando jugada");
            }
            else if(changes == 2){
                _chessBoard = chessBoard;
                //moveToken(int newColumn, int newRow)
                System.out.println("Posicion Inicial= "+ _xInicial+","+_yInicial
                        + "; Posicion Final= " + _xFinal + "," + _yFinal);
                _tablero.tokens[_yInicial][_xInicial].moveToken(_yFinal, _xFinal);
                int F = _tablero.tokens[_yInicial][_xInicial].getRow();
                int C = _tablero.tokens[_yInicial][_xInicial].getColumn();
                _tablero.tokens[C][F] = _tablero.tokens[_yInicial][_xInicial];
                _tablero.tokens[_yInicial][_xInicial] = null;
            }
            else{
                System.out.println("error");
            }
        }
        else{
            System.out.println("No cambia");
        }
    }
   
    /**
     * Method declaration
     *
     *
     * @param event
     *
     * @see
     */

   public void write(String message) throws Exception
    {
        byte[] bytes = message.getBytes();
        _out.write(bytes);
    }

   public char [][] acomodarMatriz(char [][] M){
       char [][] temporal = new char [8][8];
       for (int x = 0; x < 8; x++){
               for (int y = 0; y < 8; y++){
                   if (x == 0){
                       temporal[x][y] = M[7][y];
                   }
                   else{
                       temporal[x][y] = M[x-1][y];
                   }
               }
       }
       return temporal;
   }

    @Override
    public void serialEvent(SerialPortEvent event)
    {
	switch (event.getEventType()) {

	case SerialPortEvent.BI:

	case SerialPortEvent.OE:

	case SerialPortEvent.FE:

	case SerialPortEvent.PE:

	case SerialPortEvent.CD:

	case SerialPortEvent.CTS:

	case SerialPortEvent.DSR:

	case SerialPortEvent.RI:

	case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
	    break;

	case SerialPortEvent.DATA_AVAILABLE:
	    byte[] readBuffer = new byte[8];

	    try {
		while (inputStream.available() > 0) {
		    int numBytes = inputStream.read(readBuffer);
		} 
           //System.out.println("envía");
            try {
                write("dato"+'\n');
            } catch (Exception ex) {
                Logger.getLogger(Chess.class.getName()).log(Level.SEVERE, null, ex);
            }
           
           char newChessBoard [][] = new char [8][8];
           System.out.println();

            for(int rowIndex = 0; rowIndex < 8; rowIndex++){
               String row = Integer.toBinaryString(readBuffer[rowIndex]);
               row = (row.length() >= 8) ? (row.substring(row.length()-8, row.length()))
                       : (concatZero(row));
                if (_guardar){
                   for (int i = 0; i < 8; i++){
                   newChessBoard[rowIndex][i] = row.charAt(i);
                   }
                }

               System.out.println(row);
               }
           
           System.out.println("---------");
           newChessBoard = acomodarMatriz(newChessBoard);
           for (int x = 0; x < 8; x++){
               for (int y = 0; y < 8; y++){
                   System.out.print(newChessBoard[x][y]);
               }
               System.out.println();
           }
           System.out.println("---------**" + _guardar);
            
         if (_guardar){
             compare(newChessBoard);
             _guardar = false;
         }
         if (_contador %2 == 0){
             _guardar = true;
         }
         _contador++;

            } catch (IOException e) {
            }

	    break;
	}
    }

        public static void main(String[] args) {
            /*java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread T = new Thread();
                        T.sleep(20000);
                        new Chess(T);

                    } catch (InterruptedException e) {}
                }
            });*/

        boolean		      portFound = false;
        String		      defaultPort = "/dev/ttyUSB0";

 	if (args.length > 0) {
	    defaultPort = args[0];
	}

	portList = CommPortIdentifier.getPortIdentifiers();

	while (portList.hasMoreElements()) {
	    portId = (CommPortIdentifier) portList.nextElement();
	    if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
		if (portId.getName().equals(defaultPort)) {
		    System.out.println("Found port: "+defaultPort);
		    portFound = true;
                    Board _tablero = new Board();
                    _tablero.setVisible(true);
                    Thread T = new Thread();
		    Chess reader = new Chess(T, _tablero);

		}
	    }
	}
	if (!portFound) {
	    System.out.println("port " + defaultPort + " not found.");
	}

    } 

}


